package auctionhaus



import org.junit.*
import grails.test.mixin.*
import groovy.mock.interceptor.MockFor;

@TestFor(CustomerController)
@Mock(Customer)
class CustomerControllerTests {


	def populateValidParams(params) {
		assert params != null
		params["emailAddress"] = "bill@espn.com"
		params["password"] = "aBcDeFg"
	}

	void testIndex() {
		controller.index()
		assert "/customer/list" == response.redirectedUrl
	}

	void testList() {

		def model = controller.list()

		assert model.customerInstanceList.size() == 0
		assert model.customerInstanceTotal == 0
	}

	void testCreate() {
		def model = controller.create()

		assert model.customerInstance != null
	}

	void testSave() {
		controller.save()

		assert model.customerInstance != null
		assert view == '/customer/create'

		response.reset()

		populateValidParams(params)
		controller.save()

		assert response.redirectedUrl == '/customer/show/1'
		assert controller.flash.message != null
		assert Customer.count() == 1
	}

	void testShow() {
		controller.show()

		assert flash.message != null
		assert response.redirectedUrl == '/customer/list'


		populateValidParams(params)
		def customer = new Customer(params)

		assert customer.save() != null

		params.id = customer.id

		def model = controller.show()

		assert model.customerInstance == customer
	}

	void testEdit() {
		controller.edit()

		assert flash.message != null
		assert response.redirectedUrl == '/customer/list'


		populateValidParams(params)
		def customer = new Customer(params)

		assert customer.save() != null

		params.id = customer.id

		def model = controller.edit()

		assert model.customerInstance == customer
	}

	void testUpdate() {
		controller.update()

		assert flash.message != null
		assert response.redirectedUrl == '/customer/list'

		response.reset()


		populateValidParams(params)
		def customer = new Customer(params)

		assert customer.save() != null

		// test invalid parameters in update
		params.id = customer.id
		params["password"] = "a"

		controller.update()

		assert view == "/customer/edit"
		assert model.customerInstance != null

		customer.clearErrors()

		populateValidParams(params)
		controller.update()

		assert response.redirectedUrl == "/customer/show/$customer.id"
		assert flash.message != null

		//test outdated version number
		response.reset()
		customer.clearErrors()

		populateValidParams(params)
		params.id = customer.id
		params.version = -1
		controller.update()

		assert view == "/customer/edit"
		assert model.customerInstance != null
		assert model.customerInstance.errors.getFieldError('version')
		assert flash.message != null
	}

	void testDelete() {
		controller.delete()
		assert flash.message != null
		assert response.redirectedUrl == '/customer/list'

		response.reset()

		populateValidParams(params)
		def customer = new Customer(params)

		assert customer.save() != null
		assert Customer.count() == 1

		params.id = customer.id

		controller.delete()

		assert Customer.count() == 0
		assert Customer.get(customer.id) == null
		assert response.redirectedUrl == '/customer/list'
	}

	//C-4: An existing customer can only be deleted through the web interface if they have 0 listings and 0 bids.
	//The system will present an error message to the user if the delete cannot be performed (unit test of the controller action that has this logic)
	void testDeleteConstraints(){
		mockDomain(Bid)
		mockDomain(Listing)
		
		Customer seller = new Customer()
		seller.emailAddress="mark@live.com"
		seller.password="132242"
		
		Customer bidder = new Customer()
		bidder.emailAddress="earl@live.com"
		bidder.password="132242"

		Listing listing = new Listing()
		listing.startingPrice = 1f;
		listing.endDateTime = new Date() + 1
		listing.name = "This Thing"
		
		seller.addToListings(listing)
		
		Bid b = new Bid(amount: 2.00f)
		b.bidder = bidder;
		b.listing = listing;	
		
		assertNotNull(seller.save())
		assertNotNull(listing.save())
		assertNotNull(bidder.save())
		
		assertNotNull(b.save(failOnError:true))
		
		params.id = seller.id
		
		assert controller.delete() == null 
		assert flash.message != null
		assertEquals(flash.message, "customer.listings.delete.constraint" )
		assert response.redirectedUrl == "/customer/show/$seller.id"
		
		response.reset()
		
		params.id = bidder.id
		assert controller.delete() == null
		assert flash.message != null
		assertEquals(flash.message, "customer.bids.delete.constraint" )
		assert response.redirectedUrl == "/customer/show/$bidder.id"

	}
}
